package org.demo.base.file.controller;

import lombok.SneakyThrows;
import org.demo.base.file.domain.SysFile;
import org.demo.base.file.enums.FileType;
import org.demo.base.file.service.FileService;
import org.demo.base.mvc.HttpResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.net.URLEncoder;

/**
 * @author tomdog
 */
@RestController
public class FileController {

    @Autowired
    private FileService fileService;

    /**
     * 文件上传
     * file=文件参数
     * id=id参数
     */
    @PostMapping("/file/upload")
    public HttpResult upload(MultipartFile file, String category) {
        SysFile upload = fileService.upload(file, category);
        return HttpResult.success(upload);
    }

    /**
     * 使用路径下载文件
     * 需要考虑路径重复的问题，可以在上传文件的时候，用uuid来代替路径
     */
    @SneakyThrows
    @GetMapping("/file/{path}")
    public void download(@PathVariable String path, HttpServletResponse resp) {
        // path = "file/"+path;
        String fileName = fileService.readFileName(path);
        FileType fileType = fileService.readFileType(fileName);

        resp.setContentType(fileType.contentType());// 这种类型直接下载
        resp.setHeader("Content-Disposition",
                fileType.attachment()+";fileName="+ URLEncoder.encode(fileName, "UTF-8"));// 告诉前端我的文件名
        try(
                FileInputStream inputStream = fileService.download(path);
                ServletOutputStream out = resp.getOutputStream()
        ) {
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer))>0) {
                out.write(buffer, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
